﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using RegExStudio.RegExStudioEventArgs;

namespace RegExStudio.UserControls
{
    /// <summary>
    /// Control für die Eingabewerte die mit der RegEx verarbeitet werden sollen
    /// </summary>
    public partial class CtrlInput : CtrlGroup
    {
        /// <summary>
        /// Der String der gematcht werden soll
        /// </summary>
        public string Input
        {
            get { return txtInput.Text; }
            set { txtInput.Text = value; }
        }

        /// <summary>
        /// Die Werte die in der Eingabe reinzuersetzen sind
        /// </summary>
        public string Replacements
        {
            get { return txtReplacement.Text; }
            set { txtReplacement.Text = value; }
        }

        /// <summary>
        /// ctor
        /// </summary>
        public CtrlInput()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Control wird geladen
        /// Eingabecontrol-Hintergrundfärbung aktivieren
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CtrlInput_Load(object sender, EventArgs e)
        {
            txtInput.Enter += new EventHandler(Control_Enter);
            txtInput.Leave += new EventHandler(Control_Leave);

            txtReplacement.Enter += new EventHandler(Control_Enter);
            txtReplacement.Leave += new EventHandler(Control_Leave);
        }

        /// <summary>
        /// Der Eingabe wurde geändert
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtInput_TextChanged(object sender, EventArgs e)
        {
            OnInputChanged(txtInput.Text);
        }

        /// <summary>
        /// Wird beim Aufrufen des Kontextmenus ausgeführt
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menuInput_Opening(object sender, CancelEventArgs e)
        {
            //Das MenuItem zum Einfügen nur anzeigen, wenn auch Text im CLipboard ist
            menuInputPasteToolStripMenuItem.Enabled = Clipboard.ContainsText();
        }

        /// <summary>
        /// Kopiert den markieren Text in die Zwischenablage
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menuInputCopyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string selectedText = txtInput.Text.Substring(txtInput.SelectionStart, txtInput.SelectionLength);
            Clipboard.SetText(selectedText);
        }

        /// <summary>
        /// Kopiert das komplette Pattern in die Zwischenablage
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menuInputCopyAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Clipboard.SetText(txtInput.Text);
        }

        /// <summary>
        /// Fügt den Text in der Zwischenablage ein
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menuInputPasteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string clipBoard = Clipboard.GetText();
            if (txtInput.Text != string.Empty)
            {
                string part1 = txtInput.Text.Substring(0, txtInput.SelectionStart);
                string part2 = txtInput.Text.Substring(txtInput.SelectionStart + txtInput.SelectionLength);

                txtInput.Text = string.Format("{0}{1}{2}", part1, clipBoard, part2);
            }
            else
            {
                txtInput.Text = clipBoard;
            }
            ClearFormat();
        }

        /// <summary>
        /// Die Schriftart soll größer werden
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menuInputIncreaseFontToolStripMenuItem_Click(object sender, EventArgs e)
        {
            IncreaseFont();
        }

        /// <summary>
        /// Die Schriftart soll kleiner werden
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menuInputDecreaseFontToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DecreaseFont();
        }

        /// <summary>
        /// EventHandler für Änderung der Eingabe
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public delegate void InputChangedEventHandler(object sender, InputChangedEventArgs e);

        /// <summary>
        /// Event das ausgelöst wird, wenn die Eingabe geändert wurde
        /// </summary>
        public event InputChangedEventHandler InputChanged;

        /// <summary>
        /// Feuert das Event, wenn die Eingabe geändert wurde
        /// </summary>
        /// <param name="input"></param>
        protected virtual void OnInputChanged(string input)
        {
            if (InputChanged != null)
            {
                InputChanged(this, new InputChangedEventArgs(input));
            }
        }

        /// <summary>
        /// Der Replacements wurden geändert
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtReplacement_TextChanged(object sender, EventArgs e)
        {
            OnReplacementChanged(txtReplacement.Text);
        }

        /// <summary>
        /// EventHandler für Änderung der Replacements
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public delegate void ReplacementChangedEventHandler(object sender, ReplacementsChangedEventArgs e);

        /// <summary>
        /// Event das ausgelöst wird, wenn das Replacement geändert wurde
        /// </summary>
        public event ReplacementChangedEventHandler ReplacementChanged;

        /// <summary>
        /// Feuert das Event, wenn das Replacement geändert wurde
        /// </summary>
        /// <param name="replacement"></param>
        protected virtual void OnReplacementChanged(string replacement)
        {
            if (ReplacementChanged != null)
            {
                ReplacementChanged(this, new ReplacementsChangedEventArgs(replacement));
            }
        }

        /// <summary>
        /// Setzt die Formatierung im Eingabefeld zurück
        /// </summary>
        public void ClearFormat()
        {
            Format(0, txtInput.Text.Length, txtInput.BackColor);
        }

        /// <summary>
        /// Formatiert den angegebenen Bereich
        /// </summary>
        /// <param name="index">Begin des zu formatierenden Bereichs</param>
        /// <param name="length">Länge des zu formatierenden Bereichs</param>
        /// <param name="font">Die Schriftart des zu formatierenden Bereichs</param>
        /// <param name="backColor">Hintergrundfarbe des zu formatierenden Bereichs</param>
        public void Format(int index, int length, Color backColor)
        {
            int currentSelectionStart = txtInput.SelectionStart;
            int currentSelectionLength = txtInput.SelectionLength;

            txtInput.SelectionStart = index;
            txtInput.SelectionLength = length;
            txtInput.SelectionFont = txtInput.Font;
            txtInput.SelectionBackColor = backColor;

            txtInput.SelectionStart = currentSelectionStart;
            txtInput.SelectionLength = currentSelectionLength;
        }

        /// <summary>
        /// Selectiert den ausgewählten Bereich
        /// </summary>
        /// <param name="index">Start des Bereichs</param>
        /// <param name="length">Länge des Bereichs</param>
        public void Select(int index, int length)
        {
            this.ActiveControl = txtInput;
            txtInput.SelectionStart = index;
            txtInput.SelectionLength = length;
        }

        /// <summary>
        /// Vergrößert die Schriftart
        /// </summary>
        public void IncreaseFont()
        {
            txtInput.Font = new Font( txtInput.Font.FontFamily, txtInput.Font.Size + 1);
        }

        /// <summary>
        /// Verkleinert die Schriftart
        /// </summary>
        public void DecreaseFont()
        {
            txtInput.Font = new Font(txtInput.Font.FontFamily, txtInput.Font.Size - 1);
        }

    }
}
